/*****************************************************************************
 * Copyright (C) 2011 PELinker
 *
 * Authors: Iceberg <iceberg58744@163.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifndef __COMMON_H__
#define __COMMON_H__

#include <windows.h>

#define ERR_INVALID_COMMAND (-1)

#define ERR_DUPLICATED_OPTION (-2)
#define ERR_INCOMPLETE_OPTION (-3)
#define ERR_UNRECOGNIZED_OPTION (-4)
#define ERR_INVALID_ARGUMENT (-5)

#define ERR_MISSING_FILENAME (-6)
#define ERR_DUPLICATED_FILENAME (-7)
#define ERR_INVALID_FILENAME (-8)
#define ERR_INVALID_FILETYPE (-9)
#define ERR_INVALID_FILEHANDLE (-10)

#define ERR_UNRESOLVED_SYMBOL (-11)
#define ERR_DUPLICATED_SYMBOL (-12)

#define MAX_OPTION_NUMBER 256
#define MAX_FILE_NUMBER 256

#define MAX_SECTION_NUMBER 4096

typedef struct _String
{
	DWORD length;
	LPCTSTR ptr;
} String;

typedef struct _Option
{
	String name;
	String value;
} Option;

typedef struct _Command
{
	DWORD TotalOptionNumber;
	DWORD TotalFileNumber;

	Option options[MAX_OPTION_NUMBER];
	String files[MAX_FILE_NUMBER];
} Command;

typedef struct _Link_Option
{
	int bPrintHelpInfo;
	int bSetMapFileName;
	String MapFileName;
	int bSetOutputFileName;
	String OutputFileName;
	int bSetOutputFileType;
	DWORD OutputFileType;	/* 0 for exe, 1 for dll */
	int bSetEntryPoint;
	String EntryPoint;
	int bSetImageBase;
	DWORD ImageBase;
	int bSetSectionAlign;
	DWORD SectionAlign;
	int bSetFileAlign;
	DWORD FileAlign;
	int bSetSubsystem;
	DWORD Subsystem;	/* 1 for native, 2 for windows, 3 for console */
	int bSetLinkerVersion;
	WORD LinkerVersion[2];
	int bSetOSVersion;
	WORD OSVersion[2];
	int bSetImageVersion;
	WORD ImageVersion[2];
	int bSetSubSysVersion;
	WORD SubSysVersion[2];
	int bSetStackSize;
	DWORD StackSize;
	int bSetStackCommitSize;
	DWORD StackCommitSize;
	int bSetHeapSize;
	DWORD HeapSize;
	int bSetHeapCommitSize;
	DWORD HeapCommitSize;
} Link_Option;

struct _Relocation;

typedef struct _Section
{
	struct _Section *Next;
	BYTE *Name;
	DWORD VirtualSize;
	DWORD VirtualBaseAddress;
	DWORD VirtualAddress;
	DWORD SizeOfRawData;
	BYTE *PointerToRawData;
	struct _Relocation *PointerToRelocations;
	DWORD NumberOfRelocations;
	DWORD Characteristics;
} Section;

typedef struct _Relocation
{
	DWORD VirtualAddress;
	DWORD SymbolTableIndex;
	DWORD Type;
	Section *PointerToSection;
	VOID *PointerToSymbolTable;
} Relocation;

typedef struct _Symbol
{
	BYTE *Name;
	DWORD Value;
	DWORD LibraryIndex;
	DWORD SymbolIndex;
	Section *PointerToSection;
	DWORD Offset;
	SHORT SectionNumber;
	BYTE StorageClass;
	BYTE NumberOfAuxSymbols;
} Symbol;

typedef struct _Object
{
	DWORD NumberOfSections;
	DWORD NumberOfSymbols;

	Section *sections;
	Symbol *symbols;
} Object;

typedef struct _Library
{
	DWORD NumberOfSymbols;
	DWORD NumberOfReferences;

	BYTE LibraryName[16];
	BYTE **SymbolNames;
	BYTE **ReferenceNames;
} Library;

typedef struct _Link_Data
{
	DWORD NumberOfObjects;
	DWORD NumberOfLibraries;
	DWORD NumberOfSectionAux;

	Object objects[MAX_FILE_NUMBER];
	Library libraries[MAX_FILE_NUMBER];
	Section *sectionAux[MAX_SECTION_NUMBER];
} Link_Data;

typedef struct _IMAGE_IMPORT_DIRECTORY
{
	DWORD ImportLookupTable;
	DWORD TimeDateStamp;
	DWORD ForwarderChain;
	DWORD Name;
	DWORD ImportAddressTable;
} IMAGE_IMPORT_DIRECTORY;

typedef struct _IMAGE_PE_HEADER
{
	IMAGE_DOS_HEADER DOS_hdr;
	BYTE DOS_stub[0x40];
	DWORD NT_signature;
	IMAGE_FILE_HEADER File_hdr;
	IMAGE_OPTIONAL_HEADER Optional_hdr;
} IMAGE_PE_HEADER;

#endif
